/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.rum.reflector.telnet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author pmikulasek
 */
public class TelnetServerConections {

    private List<TelnetServer> servers;
    private File file;
    private static TelnetServerConections instance;

    private static final Logger log = LoggerFactory.getLogger(TelnetServerConections.class);

    private TelnetServerConections(File file) {
        this.servers = Collections.synchronizedList(new ArrayList<TelnetServer>());
        this.file = file;
        init();
    }

    public static TelnetServerConections getInstance() {
        if (TelnetServerConections.instance == null) {
            StringBuilder builder = new StringBuilder();
            builder.append(".");
            builder.append(File.separatorChar);
            builder.append("telnetServerConfig.tsr");

            instance = new TelnetServerConections(new File(builder.toString()));

        }
        return instance;
    }

    private void init() {
        if (!file.exists()) {
            try {
                file.createNewFile();
                save();
            } catch (IOException ex) {
                //neni mozne nacist ani ulozit servery
                log.error("It's not possible to load nor save servers", ex);
            }
        }
        if (!(file.isFile() && file.canWrite() && file.canRead())) {
            throw new IllegalArgumentException("file is can not leveraged");
        } else {

            ObjectInputStream ois = null;
            try {
                ois = new ObjectInputStream(new FileInputStream(file));

                Object obj = ois.readObject();
                if (obj instanceof List) {
                    List list = (List) obj;
                    Iterator i = list.iterator();
                    Object serverObj;
                    if (i.hasNext()) {
                        serverObj = i.next();
                        if (serverObj instanceof TelnetServer) {
                            this.servers = Collections.synchronizedList(new ArrayList<TelnetServer>(list));
                        } else {
                            //chyba nejde nacist soubor. neni to spravny format
                            log.error("The file has bad format.");
                        }
                    }
                } else {
                    // nejde nacist soubor neni to spravny format
                    log.error("The file has bad format.");
                }
//                if (this.servers == null) {
//                    this.servers = Collections.synchronizedList(new ArrayList<TelnetServer>());
//                }

            } catch (FileNotFoundException ex) {
                log.error("The file should already exists but not found.", ex);
                throw new IllegalStateException("This is fatal error because file could has already exist.", ex);
            } catch (IOException ex) {
                log.error("tak tohle je ta chyba", ex); // TODO Jirka - změnit na správnou hlášku
            } catch (ClassNotFoundException ex) {
                log.error("Probably bad structure of the file - using some old version file or application?", ex);
            } finally {
                if (ois != null) {
                    try {
                        ois.close();
                    } catch (IOException ex) {
                        //nejde zavrit soubor
                        log.error("Can't close the file,", ex);
                    }
                }
            }
        }
    }

    public List<TelnetServer> getAllServers() {
        return Collections.unmodifiableList(servers);
    }

    public synchronized TelnetServer add(TelnetServer telnetServer) {
        this.servers.add(telnetServer);
        this.save();
        return telnetServer;
    }

    public synchronized TelnetServer delete(TelnetServer telnetServer) {
        if(servers.contains(telnetServer)){
            this.servers.remove(telnetServer);
            this.save();
            return telnetServer;
        }else{
            return null;
        }
    }

    private void save() {
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(this.file));
            oos.writeObject(servers);
        } catch (FileNotFoundException ex) {
            log.error("Bad file name or path.", ex);
        } catch (IOException ex) {
            log.error("Can't save the file.", ex);
        }
    }
}
